package com.iot08.apple.pay.auth;

import okhttp3.*;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;
import java.util.List;

/**
 * @author cwj
 * @description
 * @date 2025/1/15 11:36
 **/
public class CustomAuthenticator implements Authenticator {
    // 静态实例来替代 JAVA_NET_AUTHENTICATOR
    public static final Authenticator JAVA_NET_AUTHENTICATOR = new CustomAuthenticator();

    //认证方法
    @Override
    public Request authenticate(Route route, Response response) throws IOException {
        // 获取响应中的认证挑战
        List<String> challenges = response.headers("Proxy-Authenticate"); // 代理认证头部
        if (challenges.isEmpty()) {
            challenges = response.headers("WWW-Authenticate"); // 如果没有代理认证头部，检查普通认证头部
        }

        Request request = response.request();
        URL url = request.url().url();

        boolean proxyAuthorization = response.code() == 407; // 判断是否为代理认证
        Proxy proxy = route.proxy() != null ? route.proxy() : Proxy.NO_PROXY;

        // 处理每一个认证挑战
        for (String challenge : challenges) {
            // 检查是否为 "Basic" 认证方案
            if (!challenge.toLowerCase().startsWith("basic")) {
                continue;
            }

            // 获取认证信息的领域（realm）
            String realm = parseRealm(challenge);

            // 根据是否为代理认证选择合适的处理逻辑
            PasswordAuthentication auth;
            if (proxyAuthorization) {
                InetSocketAddress proxyAddress = (InetSocketAddress) proxy.address();
                // 调用Java 1.8版本的requestPasswordAuthentication方法
                auth = java.net.Authenticator.requestPasswordAuthentication(
                        proxyAddress.getHostName(),
                        null,  // 使用null，Java 1.8中不需要传递 InetAddress
                        proxyAddress.getPort(),
                        url.getProtocol(),
                        realm,
                        "Basic"
                );
            } else {
                auth = java.net.Authenticator.requestPasswordAuthentication(
                        url.getHost(),
                        null,  // 使用null
                        url.getPort(),
                        url.getProtocol(),
                        realm,
                        "Basic"
                );
            }

            // 如果能够获取到认证信息，构造认证头并返回新的请求
            if (auth != null) {
                String credentialHeader = proxyAuthorization ? "Proxy-Authorization" : "Authorization";
                String credential = Credentials.basic(auth.getUserName(), new String(auth.getPassword()));
                return request.newBuilder()
                        .header(credentialHeader, credential)
                        .build();
            }
        }
        // 如果没有满足的挑战，返回 null
        return null;
    }

    // 认证方法
   /* @Override
    public Request authenticate(Route route, Response response) {
        // 判断路由和响应是否为空
        if (route == null || response == null) {
            return null;
        }
        // 获取代理认证信息
        PasswordAuthentication credentials = java.net.Authenticator.requestPasswordAuthentication(
                route.address().url().host(),
                null,
                route.address().url().port(),
                route.address().url().scheme(),
                "Proxy Authentication",
                null
        );

        // 如果获取到凭证信息
        if (credentials != null) {
            // 使用基础认证头构造认证信息
            String credential = okhttp3.Credentials.basic(
                    credentials.getUserName(),
                    new String(credentials.getPassword())
            );

            // 返回一个新的请求，带上代理认证头
            return response.request().newBuilder()
                    .header("Proxy-Authorization", credential)
                    .build();
        }

        // 如果没有获取到凭证信息，则返回 null，不进行认证
        return null;
    }
*/
    // 无认证的实现，类似于 Kotlin 中的 NONE
    public static final Authenticator NONE = new Authenticator() {
        @Override
        public Request authenticate(Route route, Response response) {
            return null;  // 无认证，返回 null
        }
    };

    private String parseRealm(String challenge) {
        int realmIndex = challenge.indexOf("realm=\"");
        if (realmIndex != -1) {
            int endIndex = challenge.indexOf("\"", realmIndex + 7);
            if (endIndex != -1) {
                return challenge.substring(realmIndex + 7, endIndex);
            }
        }
        return ""; // 如果没有找到realm，返回空字符串
    }
}
